﻿/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#ifndef __XOSKIT_XOS_CORE_XOS_STL_SRC_PROTOCOL_PKG_PKG_PUBLIC_FUNCTIONS_H__
#define __XOSKIT_XOS_CORE_XOS_STL_SRC_PROTOCOL_PKG_PKG_PUBLIC_FUNCTIONS_H__

#include <string>
#include "../../import/head.h"
#include "../../tools/head.h"
#include "../db/head.h"

namespace xos_protocol
{
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // res data int32 discompose 
    // 

    template< class OBJ, class T, class PACKER >
    int f_res_data_int32_dis_compose( OBJ * pObj, xos_box::i_buf * pBuf )
    {
        int ret = 0;

        xos_protocol::db_data< T, PACKER > obj( pObj->serial_ptr, pBuf );

        if( 0 == ret )
        {
            pObj->data_ptr = T::get_item_from_pool( true );
            pObj->data_ptr->init();
        }

        if( 0 == ret )
        {
            ret = obj.req_dis_compose( pObj->data_ptr );
        }

        if( 0 == ret )
        {
            ret = obj.un_pack_int32( &pObj->n_data );
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // req data int32 compose 
    // 

    template< class OBJ, class T, class PACKER, class REQUEST >
    int f_req_data_int32_compose( OBJ * pObj, REQUEST * pRequest, xos_box::i_buf * pBuf )
    {
        int ret = 0;

        xos_protocol::db_data< T, PACKER > obj( pObj->serial_ptr, pBuf );
        xos::xos_u32 uData = pRequest->m_datas[0];
        T * pT = (T*)pRequest->m_pDatas[0];

        if( 0 == ret )
        {
            ret = obj.req_compose( pRequest->m_nCookie, pRequest->m_nProtocol, pT );
        }

        if( 0 == ret )
        {
            ret = obj.pack_int32( uData );
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // req data discompose 
    // 

    template< class OBJ, class T, class PACKER, class REQUEST, class SESSION >
    int f_req_data_dis_compose( OBJ * pObj, REQUEST * pRequest, SESSION * pSession, xos_box::i_buf * pBuf )
    {
        int ret = 0;

        xos_protocol::db_data< T, PACKER > obj( pObj->serial_ptr, pBuf );
        T * pT = (T*)pRequest->m_pDatas[0];
        int nRet = 0;

        if( 0 == ret )
        {
            ret = obj.res_dis_compose( nRet, pT );
            if( ( 0 == ret ) && ( 0 != nRet ) )
            {
                pRequest->m_strs[0] = obj.m_err;
            }
        }

        {
            pSession->m_request_list.remove( pRequest );
            pRequest->m_bSuccess = 0 == nRet;
            REQUEST::response( pRequest );
            pRequest = 0;
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // req data compose 
    // 

    template< class OBJ, class T, class PACKER, class REQUEST >
    int f_req_data_compose( OBJ * pObj, REQUEST * pRequest, xos_box::i_buf * pBuf )
    {
        int ret = 0;

        xos_protocol::db_data< T, PACKER > obj( pObj->serial_ptr, pBuf );
        T * pT = (T*)pRequest->m_pDatas[0];

        if( 0 == ret )
        {
            ret = obj.req_compose( pRequest->m_nCookie, pRequest->m_nProtocol, pT );
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // res data discompose
    // 

    template< class OBJ, class T, class PACKER >
    int f_res_data_dis_compose( OBJ * pObj, xos_box::i_buf * pBuf )
    {
        int ret = 0;

        xos_protocol::db_data< T, PACKER > obj( pObj->serial_ptr, pBuf );

        if( 0 == ret )
        {
            pObj->data_ptr = T::get_item_from_pool( true );
            pObj->data_ptr->init();
        }

        if( 0 == ret )
        {
            ret = obj.req_dis_compose( pObj->data_ptr );
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // res data compose
    // 

    template< class OBJ, class T, class PACKER >
    int f_res_data_compose( OBJ * pObj, int nCookie, xos_box::i_buf * pBuf, bool & bFinished )
    {
        int ret = 0;

        xos_protocol::db_data< T, PACKER > obj( pObj->serial_ptr, pBuf );

        if( ( 0 == ret ) && ( 0 != pObj->n_ret ) )
        {
            obj.m_err = pObj->str_err;
        }

        if( 0 == ret )
        {
            ret = obj.res_compose( nCookie, pObj->n_protocol, pObj->n_ret, pObj->data_ptr );
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // req nothing discompose 
    // 

    template< class OBJ, class T, class PACKER, class REQUEST, class SESSION >
    int f_req_dis_compose( OBJ * pObj, REQUEST * pRequest, SESSION * pSession, xos_box::i_buf * pBuf )
    {
        int ret = 0;

        xos_protocol::public_base obj( pObj->serial_ptr, pBuf );
        int nRet = 0;

        if( 0 == ret )
        {
            ret = obj.res_dis_compose( nRet );
            if( ( 0 == ret ) && ( 0 != nRet ) )
            {
                pRequest->m_strs[0] = obj.m_err;
            }
        }

        {
            pSession->m_request_list.remove( pRequest );
            pRequest->m_bSuccess = 0 == nRet;
            REQUEST::response( pRequest );
            pRequest = 0;
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // res nothing compose 
    // 

    template< class OBJ, class T, class PACKER >
    int f_res_compose( OBJ * pObj, int nCookie, xos_box::i_buf * pBuf, bool & bFinished )
    {
        int ret = 0;

        xos_protocol::public_base obj( pObj->serial_ptr, pBuf );

        if( ( 0 == ret ) && ( 0 != pObj->n_ret ) )
        {
            obj.m_err = pObj->str_err;
        }

        if( 0 == ret )
        {
            ret = obj.res_compose( nCookie, pObj->n_protocol, pObj->n_ret );
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // req data int32 compose for list
    // 

    template< class OBJ, class T, class PACKER, class REQUEST >
    int f_req_data_int32_ret_list_compose( OBJ * pObj, REQUEST * pRequest, xos_box::i_buf * pBuf )
    {
        int ret = 0;

        xos_protocol::db_data< T, PACKER > obj( pObj->serial_ptr, pBuf );
        xos::xos_u32 uData = pRequest->m_datas[2];
        T * pField = (T*)pRequest->m_pDatas[0];
        T * pT = (T*)pRequest->m_pDatas[1];
        
        if( 0 == ret )
        {
            ret = obj.req_compose( pRequest->m_nCookie, pRequest->m_nProtocol, pT );
        }

        if( 0 == ret )
        {
            obj.page_size = ( xos::xos_u16 )pRequest->m_datas[0];
            obj.page_num = ( xos::xos_u16 )pRequest->m_datas[1];
            obj.cur_page = ( xos::xos_u16 )pRequest->m_datas[2];
        }

        if( 0 == ret )
        {
            obj.set_fields_by_data( pField );
            ret = obj.pack_field();
        }

        if( 0 == ret )
        {
            ret = obj.pack_page();
        }

        if( 0 == ret )
        {
            ret = obj.pck_int32( uData );
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // res data int32 discompose for list
    // 

    template< class OBJ, class T, class PACKER >
    int f_res_data_int32_ret_list_dis_compose( OBJ * pObj, xos_box::i_buf * pBuf )
    {
        int ret = 0;

        xos_protocol::db_data< T, PACKER > obj( pObj->serial_ptr, pBuf );

        if( 0 == ret )
        {
            pObj->data_ptr = T::get_item_from_pool( true );
            pObj->data_ptr->init();
        }

        if( 0 == ret )
        {
            ret = obj.req_dis_compose( pObj->data_ptr );
        }

        if( 0 == ret )
        {
            ret = obj.un_pack_field();
        }

        if( 0 == ret )
        {
            ret = obj.un_pack_page();
        }

        if( 0 == ret )
        {
            ret = obj.un_pack_int32( &pObj->n_data );
        }

        if( 0 == ret )
        {
            ret = obj.get_fields( pObj->field_num, pObj->fields );
        }

        if( 0 == ret )
        {
            pObj->page_size = obj.page_size;
            pObj->page_num = obj.page_num;
            pObj->cur_page = obj.cur_page;
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // req data compose for list
    // 

    template< class OBJ, class T, class PACKER, class REQUEST >
    int f_req_data_ret_list_compose( OBJ * pObj, REQUEST * pRequest, xos_box::i_buf * pBuf )
    {
        int ret = 0;

        xos_protocol::db_data< T, PACKER > obj( pObj->serial_ptr, pBuf );
        T * pField = (T*)pRequest->m_pDatas[0];
        T * pT = (T*)pRequest->m_pDatas[1];

        if( 0 == ret )
        {
            ret = obj.req_compose( pRequest->m_nCookie, pRequest->m_nProtocol, pT );
        }

        if( 0 == ret )
        {
            obj.page_size = ( xos::xos_u16 )pRequest->m_datas[0];
            obj.page_num = ( xos::xos_u16 )pRequest->m_datas[1];
            obj.cur_page = ( xos::xos_u16 )pRequest->m_datas[2];
        }

        if( 0 == ret )
        {
            obj.set_fields_by_data( pField );
            ret = obj.pack_field();
        }

        if( 0 == ret )
        {
            ret = obj.pack_page();
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // res data discompose for list
    // 

    template< class OBJ, class T, class PACKER >
    int f_res_data_ret_list_dis_compose( OBJ * pObj, xos_box::i_buf * pBuf )
    {
        int ret = 0;

        xos_protocol::db_data< T, PACKER > obj( pObj->serial_ptr, pBuf );

        if( 0 == ret )
        {
            pObj->data_ptr = T::get_item_from_pool( true );
            pObj->data_ptr->init();
        }

        if( 0 == ret )
        {
            ret = obj.req_dis_compose( pObj->data_ptr );
        }

        if( 0 == ret )
        {
            ret = obj.un_pack_field();
        }

        if( 0 == ret )
        {
            ret = obj.un_pack_page();
        }

        if( 0 == ret )
        {
            ret = obj.get_fields( pObj->field_num, pObj->fields );
        }

        if( 0 == ret )
        {
            pObj->page_size = obj.page_size;
            pObj->page_num = obj.page_num;
            pObj->cur_page = obj.cur_page;
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // req nothing compose for list with page
    // 

    template< class OBJ, class T, class PACKER, class REQUEST >
    int f_req_ret_list_compose_dic( OBJ * pObj, REQUEST * pRequest, xos_box::i_buf * pBuf )
    {
        int ret = 0;

        xos_protocol::public_field< T, PACKER > obj( pObj->serial_ptr, pBuf );

        for( int i = 0; ( 0 == ret ) && ( i < T::FIELD_NUM ); ++i )
        {
            obj.fields[obj.field_num++] = ( xos::xos_u8 )i;
        }

        ret = obj.req_compose( pRequest->m_nCookie, pRequest->m_nProtocol );

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // res nothing dis compose for list with page
    // 

    template< class OBJ, class T, class PACKER >
    int f_res_ret_list_dis_compose_dic( OBJ * pObj, xos_box::i_buf * pBuf )
    {
        int ret = 0;

        xos_protocol::public_field< T, PACKER > obj( pObj->serial_ptr, pBuf );

        if( 0 == ret )
        {
            ret = obj.req_dis_compose();
        }

        if( 0 == ret )
        {
            ret = obj.get_fields( pObj->field_num, pObj->fields );
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // req nothing compose for list with page
    // 

    template< class OBJ, class T, class PACKER, class REQUEST >
    int f_req_ret_list_compose( OBJ * pObj, REQUEST * pRequest, xos_box::i_buf * pBuf )
    {
        int ret = 0;

        xos_protocol::db_get< T, PACKER > obj( pObj->serial_ptr, pBuf );
        T * pField = (T*)pRequest->m_pDatas[0];

        if( 0 == ret )
        {
            obj.page_size = ( xos::xos_u16 )pRequest->m_datas[0];
            obj.page_num = ( xos::xos_u16 )pRequest->m_datas[1];
            obj.cur_page = ( xos::xos_u16 )pRequest->m_datas[2];
            obj.set_fields_by_data( pField );
        }

        ret = obj.req_compose( pRequest->m_nCookie, pRequest->m_nProtocol );

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // res nothing dis compose for list with page
    // 

    template< class OBJ, class T, class PACKER >
    int f_res_ret_list_dis_compose( OBJ * pObj, xos_box::i_buf * pBuf )
    {
        int ret = 0;

        xos_protocol::db_get< T, PACKER > obj( pObj->serial_ptr, pBuf );

        if( 0 == ret )
        {
            ret = obj.req_dis_compose();
        }

        if( 0 == ret )
        {
            ret = obj.get_fields( pObj->field_num, pObj->fields );
        }

        if( 0 == ret )
        {
            pObj->page_size = obj.page_size;
            pObj->page_num = obj.page_num;
            pObj->cur_page = obj.cur_page;
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // req int32 compose for list with page
    // 

    template< class OBJ, class T, class PACKER, class REQUEST >
    int f_req_int32_ret_list_compose( OBJ * pObj, REQUEST * pRequest, xos_box::i_buf * pBuf )
    {
        int ret = 0;

        xos_protocol::db_get< T, PACKER > obj( pObj->serial_ptr, pBuf );
        xos::xos_u32 uData = pRequest->m_datas[3];
        T * pField = (T*)pRequest->m_pDatas[0];

        if( 0 == ret )
        {
            obj.page_size = ( xos::xos_u16 )pRequest->m_datas[0];
            obj.page_num = ( xos::xos_u16 )pRequest->m_datas[1];
            obj.cur_page = ( xos::xos_u16 )pRequest->m_datas[2];
            obj.set_fields_by_data( pField );
        }

        if( 0 == ret )
        {
            ret = obj.req_compose( pRequest->m_nCookie, pRequest->m_nProtocol );
        }

        if( 0 == ret )
        {
            ret = obj.pack_int32( uData );
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // res int32 dis compose for list with page
    // 

    template< class OBJ, class T, class PACKER >
    int f_res_int32_ret_list_dis_compose( OBJ * pObj, xos_box::i_buf * pBuf )
    {
        int ret = 0;

        xos_protocol::db_get< T, PACKER > obj( pObj->serial_ptr, pBuf );

        if( 0 == ret )
        {
            ret = obj.req_dis_compose();
        }

        if( 0 == ret )
        {
            ret = obj.un_pack_int32( &pObj->n_data );
        }

        if( 0 == ret )
        {
            ret = obj.get_fields( pObj->field_num, pObj->fields );
        }

        if( 0 == ret )
        {
            pObj->page_size = obj.page_size;
            pObj->page_num = obj.page_num;
            pObj->cur_page = obj.cur_page;
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // req list compose for list
    // 

    template< class OBJ, class T, class PACKER, class REQUEST >
    int f_req_list_ret_list_compose( OBJ * pObj, REQUEST * pRequest, xos_box::i_buf * pBuf )
    {
        int ret = 0;

        xos_protocol::db_get< T, PACKER > obj( pObj->serial_ptr, pBuf );
        T * pField = (T*)pRequest->m_pDatas[0];
        T * pT = (T*)pRequest->m_pDatas[1];

        if( 0 == ret )
        {
            obj.set_fields_by_data( pT );
            ret = obj.req_compose_with_list( pRequest->m_nCookie, pRequest->m_nProtocol, &pT->m_list );
        }

        if( 0 == ret )
        {
            obj.page_size = ( xos::xos_u16 )pRequest->m_datas[0];
            obj.page_num = ( xos::xos_u16 )pRequest->m_datas[1];
            obj.cur_page = ( xos::xos_u16 )pRequest->m_datas[2];
            ret = obj.pack_page();
        }

        if( 0 == ret )
        {
            obj.set_fields_by_data( pField );
            ret = obj.pack_field();
        }

        pT->m_list.put_back_to_pool( true );

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // res list dis compose for list
    // 

    template< class OBJ, class T, class PACKER >
    int f_res_list_ret_list_dis_compose( OBJ * pObj, xos_box::i_buf * pBuf )
    {
        int ret = 0;

        xos_protocol::db_get< T, PACKER > obj( pObj->serial_ptr, pBuf );

        if( 0 == ret )
        {
            pObj->data_ptr = T::get_item_from_pool( true );
            pObj->data_ptr->init();
        }

        if( 0 == ret )
        {
            ret = obj.req_dis_compose_with_list( &pObj->data_ptr->m_list );
        }

        if( 0 == ret )
        {
            ret = obj.get_fields_to_data( pObj->data_ptr );
        }

        if( 0 == ret )
        {
            ret = obj.un_pack_page();
        }

        if( 0 == ret )
        {
            ret = obj.un_pack_field();
        }

        if( 0 == ret )
        {
            ret = obj.get_fields( pObj->field_num, pObj->fields );
        }

        if( 0 == ret )
        {
            pObj->page_size = obj.page_size;
            pObj->page_num = obj.page_num;
            pObj->cur_page = obj.cur_page;
        }

        return ret;
    }

} // xos_protocol

#endif // __XOSKIT_XOS_CORE_XOS_STL_SRC_PROTOCOL_PKG_PKG_PUBLIC_FUNCTIONS_H__
